import java.util.regex.Pattern;
import java.util.List;
import java.util.Iterator;
import java.lang.StringBuffer;

import javax.swing.text.html.HTMLDocument.Iterator;

import org.zkoss.zk.ui.AbstractComponent;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.api.Div;
import org.zkoss.zul.api.Label;
import org.zkoss.zul.api.Listbox;
import org.zkoss.zul.Image;
import org.zkoss.zul.api.Listitem;
import org.zkoss.zul.impl.InputElement;
import org.zkoss.zul.api.Combobox;
import org.zkoss.zul.ext.Constrainted;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.impl.InputElement;

import validation.VFormProcessor;

public class VFormController extends Window
{
	private static final int LOW,MID,HIGH;
	private Window indicator;
	private Window indicatorBar;
	private Label indicatorLabel;
	private Listbox formList;
	private Listitem floatRow,nextRow;
	private Listitem floatRowCheck,nextRowCheck;
	private Div tip;
	private String loadingImg="VCodeGenerator/loading.gif",
				   nameOKImg,
				   nameUsedImg;
	private Image checkImg=null;
	private Combobox selector;
	
	public void initialize(){
		indicator=((Window)getFellow("VF_INDICATOR"));
		indicatorBar=((Window)indicator.getChildren().get(0));
		indicatorLabel=((Label)getFellow("VF_INDICATOR_LABEL"));
		
		formList=((Listbox)getFellow("VF_FORM_LIST"));
		floatRow=((Listitem)getFellow("VF_FLOAT_ROW"));
		formList.removeChild(floatRow);
		nextRow=((Listitem)getFellow("VF_PASSWORD_CONFIRM_ROW"));
		
		tip=((Div)getFellow("VF_TIP"));
		
		floatRowCheck=((Listitem)getFellow("VF_CHECK_USERNAME_ROW"));
		nextRowCheck=((Listitem)getFellow("VF_PASSWORD_ROW"));
		formList.removeChild(floatRowCheck);
		//formList.addEventListener("onNotify", new VFormProcessor());
	}
	
	public void registerSelector(Component comp){
		selector=(Combobox)comp;
		selector.setSelectedIndex(6);
	}
	
	public void checkPassword(){
		String password=((Textbox)getFellow("VF_PASSWORD_BOX")).getValue();
		int score=getScore(password);
		if(((Textbox)getFellow("VF_PASSWORD_BOX")).getValue().equals("") 
		   && formList.getIndexOfItem(floatRow) != -1)
		{formList.removeChild(floatRow);return;}
		else if(floatRow.getParent() != formList)
			formList.insertBefore(floatRow, nextRow);

		if(score >= HIGH){
			indicatorBar.setWidth("150px");
			indicatorBar.setStyle("background:#28ff28");
			indicatorLabel.setValue("HIGH");
		}else if(score >= MID){
			indicatorBar.setWidth("100px");
			indicatorBar.setStyle("background:#f9f900");
			indicatorLabel.setValue("MIDDLE");
		}else if(score >= LOW){
			indicatorBar.setWidth("33px");
			indicatorBar.setStyle("background:#ff5151");
			indicatorLabel.setValue("LOW");
		}else{
			indicatorBar.setWidth("0px");
			indicatorLabel.setValue("NOT VALID");
		}
	}
	
	private int getScore(String str){
		int intScore=0;
		if (Pattern.matches("[a-z]*",str))
			intScore = (intScore+1);
		if (Pattern.matches("[A-Z]*",str))
			intScore = (intScore+5);
		if (Pattern.matches("\\d+",str))
			intScore = (intScore+5);
		if (Pattern.matches("(\\d.*\\d.*\\d)",str))
			intScore = (intScore+5);
		if (Pattern.matches("[!,@#$%^&*?_~]*",str))
			intScore = (intScore+5);
		if (Pattern.matches("([!,@#$%^&*?_~].*[!,@#$%^&*?_~])",str))
			intScore = (intScore+5);
		if (Pattern.matches("[a-z]",str) 
			&& Pattern.matches("[A-Z]",str))
			intScore = (intScore+2);
		if (Pattern.matches("\\d",str) 
			  && Pattern.matches("\\D",str))
			intScore = (intScore+2);
		if (Pattern.matches("[a-z]",str)
			&& Pattern.matches("[A-Z]",str) 
			&& Pattern.matches("\\d",str) 
			&& Pattern.matches("[!,@#$%^&*?_~]",str))
			intScore = (intScore+2);
		
		return intScore;
	}
	
	public void showCheck(Component text){
		String str=((Textbox)text).getValue();

		if(str.length() == 0 && floatRowCheck.getParent() == formList)
			{formList.removeChild(floatRowCheck);return;}
		else if(str.length() != 0 && floatRowCheck.getParent() == null)
		{
			formList.insertBefore(floatRowCheck,nextRowCheck);
			if(checkImg == null)
				checkImg=((Image)text.getFellow("VF_CHECK_USERNAME_IMAGE"));
			checkImg.setVisible(false);
		}
	}
	
	public void checkName(Component but){
		formList.setAttribute("EVENT_TYPE", "CHECK_NAME");
		Events.echoEvent("onNotify",formList,"");
		checkImg.setSrc(loadingImg);
		checkImg.setVisible(true);
	}
	
	public void setTip(Component comp){
		if(comp == null)return;
		
		String jump=comp.getAttribute("jumpHelp");
		
		if(jump == null || jump.equals("") || jump.equalsIgnoreCase("null")){
			if(jump == null || jump.equalsIgnoreCase("null"))
			{
				tip.setVisible(false);
				return;
			}else tip.setVisible(true);
			
			tip.setVisible(true);
			String info=comp.getAttribute("position");
			String lineHeight=formList.getAttribute("lineHeight");
			
			Component item=comp;
			while(!(item instanceof Listitem))
				item=item.getParent();
			
			if(info != null && !info.equals("") &&
			   lineHeight != null && !lineHeight.equals(""))
				tip.setStyle("margin-top:"+
							 (formList.getIndexOfItemApi(item)*
							  Integer.parseInt(formList.getAttribute("lineHeight"))
							  +Integer.parseInt(info)
							 )+
							 "px");
			
			info=comp.getAttribute("helpInfo");
			if(info != null && !info.equals(""))
				((Label)tip.getFellow("VF_TIP_TEXT")).
					setValue(info.replace('#', '\n'));		
			
			info=comp.getAttribute("lengthImg");
			if(info != null && !info.equals(""))
				((Image)comp.getFellow("VF_BACKGROUND_IMG_TIP")).setHeight(info+"px");
		
		}else setTip(formList.getFellow(jump));
		
	}
	
	public void reset(){
		reset(this);
		selector.setSelectedIndex(6);
	}
	
	private void reset(AbstractComponent root){
		if(root == null)return;
		if(root instanceof InputElement)
			((InputElement)root).setText("");
		else if(root == tip)
			root.setVisible(false);
		else if(root == floatRow || root == floatRowCheck)
			root.setParent(null);
		else if(root instanceof Radiogroup)
			((Radiogroup)root).setSelectedIndex(-1);
		else if(root instanceof Image && 
				((Image)root).getSrc() != null &&
			    (((Image)root).getSrc().indexOf("check.png") != -1 ||
			     ((Image)root).getSrc().indexOf("cross.png") != -1))
			root.setParent(null);
		
		List children=root.getChildren();
		int size=children.size();
		for(int i=0;i < size;i++){
			reset(children.get(i));
			if(children.size() < size){
				size--;
				i--;
			}
		}
	}
	
	public void submitForm(){
		if(!checkForm(this))return;
		formList.setAttribute("EVENT_TYPE", "SUBMIT_FORM");
		Events.echoEvent("onNotify",formList,"");
	}
	
	private boolean checkForm(Component root){
		boolean answer=true;
		int size=root.getChildren().size();
		for(int i=0;i < size;i++){
			Component cmp=(Component)root.getChildren().get(i);
			
			if(cmp.getAttribute("unnecessary") != null && cmp.getAttribute("unnecessary").equals("true"))
				continue;
			
			if(cmp instanceof InputElement){
				int check=check((InputElement)cmp);
				if(check <= 0){
					showCheckImg(cmp,false);
					answer=false;
				}else showCheckImg(cmp,true);
			}else if(cmp instanceof Radiogroup){
				int selIndex=((Radiogroup)cmp).getSelectedIndex();
				if(selIndex == -1){
					showCheckImg(cmp,false);
					ans=false;
				}else showCheckImg(cmp,true);
			}
			
			answer=checkForm(cmp) == false ? false : answer;
		}
		
		return answer;
	}
	
	//0 fail
	//1 succeed
	//-1 empty
	public int check(InputElement b){
		return 0;
	}
	
	public int validateInput(InputElement b){
		
		if(b.getAttribute("unnecessary") != null && b.getAttribute("unnecessary").equals("true"))
			return 1;
		
		int checkRes=check(b);
		if(b==-1)return;
		
		Component item=b;
		while(!(item instanceof Listitem))
			item=item.getParent();	
		
		Image img=new Image(b == 1 ? "../validation/check.png" : "../validation/cross.png");
		while(item.getLastChild().getChildren().size() > 1)
			item.getLastChild().removeChild(item.getLastChild().getLastChild());
		img.setParent(item.getLastChild());
		
		if(b.getAttribute("imgMargin") != null && !b.getAttribute("imgMargin").equals(""))
			img.setStyle("margin-left:"+b.getAttribute("imgMargin"));
		
		return checkRes;
	}
	
	public void showCheckImg(Component b,boolean ok){
		if(b==-1)return;
		
		Component item=b;
		while(!(item instanceof Listitem))
			item=item.getParent();
	
		Image img=new Image(ok == true ? "../validation/check.png" : "../validation/cross.png");
		while(item.getLastChild().getChildren().size() > 1)
			item.getLastChild().removeChild(item.getLastChild().getLastChild());
		img.setParent(item.getLastChild());
		
		if(b.getAttribute("imgMargin") != null && !b.getAttribute("imgMargin").equals(""))
			img.setStyle("margin-left:"+b.getAttribute("imgMargin"));
	}
}